<template>
  <div class="chart-container">
    <Config @change="handleChartRefresh" v-if="isDataReady" />
    <Template v-if="isDataReady" ref="templateRef" />
    <el-row v-if="isDataReady && chartDataList.length">
      <el-col
        :sm="24"
        :md="Math.max(8, 24 / chartDataList.length)"
        v-for="(data, idx) in chartDataList"
        class="chart-col"
      >
        <div class="chart-header">
          <div class="chart-title">
            <el-icon><Histogram /></el-icon>
            <span> {{ data.title }}</span>
          </div>
          <el-button type="danger" link @click="handleRemoveTemplate(idx)">
            <el-icon><CircleCloseFilled /></el-icon>
          </el-button>
        </div>
        <el-scrollbar
          :ref="(el) => setScrollbarRef(idx, el)"
          @wheel="(e) => handleMouseWheel(idx, e)"
          @scroll="(e) => handleScroll(idx, e)"
        >
          <div class="chart-content">
            <Chart
              :ref="(el) => setChartRef(idx, el)"
              :chartData="data"
              :yMax="chartYaxisMax"
              @chartClick="handleChartClick"
            />
          </div>
        </el-scrollbar>
      </el-col>
    </el-row>
  </div>
</template>

<script setup>
import {
  ref,
  computed,
  nextTick,
  watch,
  onMounted,
  onUnmounted,
  onBeforeUpdate,
  h,
} from "vue";

import useFlowStore from "@/store/flow.js";
import Config from "./Config.vue";
import Chart from "./Chart.vue";
import Generator from "./Generator.js";
import Template from "./Template.vue";
import ConfigDefault from "./Config.js";

const flowStore = useFlowStore();

const isDataReady = computed(() => flowStore.chartConfig.freeChart);

const chartDataList = computed(() => {
  return flowStore.chartConfig.freeChart.appliedTemplateList.map((template) => {
    return Generator({
      rawData: flowStore.rawData,
      tags: flowStore.tags,
      begTime: flowStore.begTime,
      dataInterval: flowStore.chartConfig.freeChart.dataInterval,
      dataStep: flowStore.chartConfig.freeChart.dataStep,
      template: template,
    });
  });
});

const chartYaxisMax = computed(() => {
  if (!flowStore.chartConfig.freeChart.syncYaxisMax) return null;
  if (chartDataList.value.length <= 1) return null;
  const max =
    Math.ceil(Math.max(...chartDataList.value.map((data) => data.max)) / 10) *
    10;
  return max > 0 ? max : null;
  // 以10为单位向上取整
});

const scrollbarRefs = ref(new Map());

const setScrollbarRef = (id, el) => {
  if (el) {
    scrollbarRefs.value.set(id, el);
  } else {
    scrollbarRefs.value.delete(id);
  }
};

const handleMouseWheel = (idx, e) => {
  const wheelDelta = e.wheelDelta || -e.deltaY * 40;
  const sourceScrollbar = scrollbarRefs.value.get(idx);
  const scrollLeft = sourceScrollbar.wrapRef.scrollLeft - wheelDelta;
  sourceScrollbar.setScrollLeft(scrollLeft);
  // for (let i = 0; i < chartDataList.value.length; i++) {
  //   if (i !== idx) {
  //     const targetScrollbar = scrollbarRefs.value.get(i);
  //     targetScrollbar.setScrollLeft(sourceScrollbar.wrapRef.scrollLeft);
  //   }
  // }
};

const handleScroll = (idx, e) => {
  if (!flowStore.chartConfig.freeChart.syncScroll) return;
  for (let i = 0; i < chartDataList.value.length; i++) {
    if (i !== idx) {
      const targetScrollbar = scrollbarRefs.value.get(i);
      targetScrollbar.setScrollLeft(e.scrollLeft);
    }
  }
};

const chartRefs = ref(new Map());

const setChartRef = (id, el) => {
  if (el) {
    chartRefs.value.set(id, el);
  } else {
    chartRefs.value.delete(id);
  }
};

const handleChartRefresh = () => {
  nextTick(() => {
    for (let chart of chartRefs.value.values()) {
      chart.refresh();
    }
  });
};

const handleChartClick = () => {};

const templateRef = ref();

const handleRemoveTemplate = (idx) => {
  templateRef.value.removeChartTemplate(idx);
  nextTick(() => {
    handleChartRefresh();
  });
};

onMounted(() => {
  if (!flowStore.chartConfig.freeChart) {
    flowStore.chartConfig.freeChart = JSON.parse(JSON.stringify(ConfigDefault));
  }
  window.addEventListener("resize", () => {
    handleChartRefresh();
  });
});

onBeforeUpdate(() => {
  scrollbarRefs.value.clear();
  chartRefs.value.clear();
});
</script>

<style scoped>
.chart-container {
  min-height: calc(100vh - 155px);
}

.chart-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 12px 0 16px;
  /* background-color: var(--el-fill-color-darker); */
}

.chart-title {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1;
  color: var(--el-text-color-primary);
  font-size: 14px;
  font-weight: bold;
}

.chart-col:not(:first-child) {
  border-left: 1px solid var(--el-border-color);
}
</style>
